package com.amtf.datafile3.core.fil.parser;

import java.util.ArrayList;
import java.util.List;

import com.amtf.datafile3.DataException;
import com.amtf.datafile3.DataFieldDefinition;
import com.amtf.datafile3.DataFieldType;
import com.amtf.datafile3.DataRecord;
import com.amtf.datafile3.DataRecordParser;
import com.amtf.datafile3.DataTableDefinition;
import com.amtf.datafile3.cfg.fil.FilDataFieldDefinition;
import com.amtf.datafile3.cfg.std.StdDataTableDefinition;
import com.amtf.datafile3.cfg.xsv.XsvDataFieldDefinition;
import com.amtf.datafile3.core.std.AbsDataRecordParser;
import com.amtf.datafile3.core.std.type.StringFieldType;

public class FilDataRecordParser extends AbsDataRecordParser<String, String> {
	// int[] columnStartIndex;

	// public FilDataRecordParser(int[] columnStartIndex) {
	// this.columnStartIndex = columnStartIndex;
	// }

	@Override
	public DataRecordParser<String, String> clone() {
		FilDataRecordParser newObj = new FilDataRecordParser();
		return newObj;
	}

	public DataRecord parse(DataTableDefinition definition, DataRecord record) throws DataException {
		DataRecord newrecord = definition.newDataRecordInstance();
		newrecord.set(record.getValues());
		return newrecord;
	}

	public DataRecord parse(DataTableDefinition definition, String record) throws DataException {
		String[] fieldValues = split((String) record, definition.getFieldCount());
		return definition.newDataRecordInstance().parse(fieldValues);
	}

	public DataRecord parse(DataTableDefinition definition, String[] fields) throws DataException {
		return definition.newDataRecordInstance().parse(fields);
	}

	public void resetColumnLike(DataTableDefinition fromDefinition, DataTableDefinition toDefinition) {
		toDefinition.removeAll();
		int startIndex = 0, lastLength = 0;
		for (int i = 0; i < fromDefinition.getFieldCount(); i++) {
			DataFieldDefinition fieldDef = fromDefinition.getField(i);

			if (fieldDef instanceof FilDataFieldDefinition) {
				FilDataFieldDefinition xsvdef = (FilDataFieldDefinition) fieldDef.clone();
				toDefinition.addField(xsvdef);
			} else {
				startIndex = lastLength;
				DataFieldType type = fieldDef.getType().clone();
				toDefinition.addField(new FilDataFieldDefinition(fieldDef.getName(), type, startIndex, type.getTotalLength(), null, null));
				lastLength = type.getTotalLength();
			}
		}
	}

	public void detectColumn(DataTableDefinition definition, String titleRow, boolean isTitle) throws DataException {
		if (titleRow != null && titleRow.length() != 0) {
			if (definition.getFieldCount() == 0) {
				DataFieldType type = new StringFieldType(titleRow.length(), true, null);

				definition.addField(new FilDataFieldDefinition(null, type, 0, titleRow.length(), null, null));
			} else if (isTitle) {
				int beginIndex = 0, lastLength = 0;
				List<DataFieldDefinition> fields = definition.getFields();
				for (int i = 0; i < fields.size(); i++) {
					FilDataFieldDefinition fd = (FilDataFieldDefinition) fields.get(i);
					beginIndex += lastLength;
					String title = titleRow.substring(beginIndex, beginIndex + fd.getLength());
					if (fd.getName().length() == 0 || fd.getName().startsWith(StdDataTableDefinition.DEFAULT_COLNAME)) {
						fd.setName(title.trim());
					}
					lastLength = fd.getLength();
				}
			}
		}
	}

	public static String[] split(String row, int columnCount) throws DataException {
		String[] strs = new String[columnCount];
		for (int i = 0; i < strs.length; i++) {
			strs[i] = row;
		}
		return strs;
	}

	// public static String[] split(String row, int[] columnStartIndex) throws DataException {
	// List<String> strs = new ArrayList<String>();
	//
	// int length = row.length();
	// if (length > 0) {
	// int max = columnStartIndex.length - 1;
	// for (int i = 0; i < max; i++) {
	// strs.add(row.substring(columnStartIndex[i], columnStartIndex[i + 1]));
	// }
	//
	// strs.add(row.substring(columnStartIndex[max]));
	// }
	//
	// String[] result = new String[strs.size()];
	// strs.toArray(result);
	// return result;
	// }

}
